home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / netBoot.new / dev / if_le.c < prev    next >
C/C++ Source or Header  |  1990-12-19  |  12KB  |  464 lines

  1. #ifdef    M25
  2. #ifndef lint
  3. static    char sccsid[] = "@(#)if_le.c 1.1 86/09/27 Copyr 1986 Sun Micro";
  4. #endif
  5.  
  6. /*
  7.  * Copyright (c) 1986 by Sun Microsystems, Inc.
  8.  */
  9.  
  10. /*****************************************************************************
  11.  * 10-Dec-85
  12.  *     ADD signal user that we have lost carrier (or couldn't find it).
  13.  *        This usually means that the cable is bad
  14.  *
  15.  *****************************************************************************/
  16.  
  17. /*
  18.  * For Sun-3/25 debugging we want DEBUG on.  For production, turn it off.
  19.  */
  20. /* #define DEBUG1 */
  21. /* #define DEBUG    1 */
  22.  
  23. #define LANCEBUG 1    /* Rev C Lance chip bug */
  24. #define PROTOSCRATCH 8192
  25.  
  26. /* 
  27.  * Parameters controlling TIMEBOMB action: times out if chip hangs.
  28.  *
  29.  */
  30. #define    TIMEBOMB    1000000    /* One million times around is all... */
  31.  
  32. /*
  33.  * Sun Lance Ethernet Controller interface
  34.  */
  35. #include "../dev/saio.h"
  36. #include "../h/param.h"
  37. #include "../h/socket.h"
  38. #include "../dev/if_lereg.h"
  39. #include "../dev/if.h"
  40. #include "../h/in.h"
  41. #include "../dev/if_ether.h"
  42. #include "../h/idprom.h"
  43. #include "../sun3/cpu.map.h"
  44.  
  45. /* Determine whether we are PROM or not. */
  46. /* #define PROM 1 */
  47.  
  48. int    lancexmit(), lancepoll(), lancereset();
  49.  
  50. struct saif leif = {
  51.     lancexmit,
  52.     lancepoll,
  53.     lancereset,
  54. };
  55.  
  56. #define    LANCERBUFSIZ    1600
  57. #define    LANCETBUFSIZ    1600
  58.  
  59. struct lance_softc {
  60. /*     char        es_scrat[PROTOSCRATCH];    /* work space for nd  */
  61.         struct le_device        *es_lance;    /* Device register address */
  62.     struct ether_addr    es_enaddr;    /* Our Ethernet address */
  63.     struct le_init_block    es_ib;        /* Initialization block */
  64.     u_char            fill[6];
  65.     struct le_md        es_rmd[2];    /* Receive Descriptor Ring */
  66.     struct le_md        es_tmd;        /* Transmit Descriptor Ring */
  67.     u_char            es_rbuf[2][LANCERBUFSIZ]; /* Receive Buffers */
  68. #ifndef PROM
  69.     u_char            es_tbuf[LANCETBUFSIZ];    /* Transmit Buffer */
  70. #endif    PROM
  71.     int            es_next_rmd;    /* Next descriptor in ring */
  72. };
  73.  
  74. /*
  75.  * Need to initialize the Ethernet control reg to:
  76.  *    Reset is active
  77.  *    Loopback is NOT active
  78.  *    Interrupt enable is not active.
  79.  */
  80. u_long lancestd[] = {VIOPG_AMD_ETHER << BYTES_PG_SHIFT};
  81.  
  82. struct devinfo lanceinfo = {
  83.     sizeof (struct le_device),
  84.     sizeof (struct lance_softc),
  85.     0,                /* Local bytes (we use dma) */
  86.     1,                /* Standard addr count */
  87.     lancestd,            /* Standard addrs */
  88.     MAP_OBIO,            /* Device type */
  89.     0,                /* transfer size handled by ND */
  90. };
  91.  
  92. int lanceprobe(), tftpboot(), lanceopen(), lanceclose(), etherstrategy();
  93. int nullsys();
  94.  
  95. struct boottab ledriver = {
  96.     "le", lanceprobe, tftpboot, lanceopen, lanceclose,
  97.     etherstrategy, "le: Sun/Lance Ethernet", &lanceinfo,
  98. };
  99.  
  100. extern struct ether_addr etherbroadcastaddr;
  101.  
  102. /*
  103.  * Probe for device.
  104.  * Must return -1 for failure for monitor probe
  105.  */
  106. lanceprobe(sip)
  107.     struct saioreq *sip;
  108. {
  109.     register short *sp;
  110.     struct idprom id;
  111.  
  112.     if (IDFORM_1 == idprom(IDFORM_1, &id)
  113.         && id.id_machine == IDM_SUN3_M25)
  114.         return (0);
  115.     else
  116.         return (-1);
  117. }
  118.  
  119. /*
  120.  * Open Lance Ethernet nd connection, return -1 for errors.
  121.  */
  122. lanceopen(sip)
  123.     struct saioreq *sip;
  124. {
  125.     register int result;
  126.  
  127. #ifdef DEBUG1
  128.     printf("le: lanceopen[\n");
  129. #endif DEBUG1
  130.     sip->si_sif = &leif;
  131.     if ( lanceinit(sip) || (result = etheropen(sip)) < 0 ) {
  132.         lanceclose(sip);        /* Make sure we kill chip */
  133. #ifdef DEBUG1
  134.         printf("le: lanceopen --> -1\n");
  135. #endif DEBUG1
  136.         return (-1);
  137.     }
  138. #ifdef DEBUG1
  139.     printf("le: lanceopen --> %x\n", result);
  140. #endif DEBUG1
  141.     return (result);
  142. }
  143.  
  144. /*
  145.  * Set up memory maps and Ethernet chip.
  146.  * Returns 1 for error (after printing message), 0 for ok.
  147.  */
  148. int
  149. lanceinit(sip)
  150.     struct saioreq *sip;
  151. {
  152.     register struct lance_softc *es;
  153.     int paddr;
  154.     int i;
  155.     struct idprom id;
  156.     
  157.     /* 
  158.      * Our locals were obtined from DMA space, now put the locals
  159.      * pointer in the standard place.  This is OK since close()
  160.      * will only deallocate from devdata if its size in devinfo is >0.
  161.      */
  162.     es = (struct lance_softc *)sip->si_dmaaddr;
  163.     sip->si_devdata = (caddr_t)es;
  164.     es->es_lance = (struct le_device *) sip->si_devaddr;
  165.  
  166.     if (IDFORM_1 != idprom(IDFORM_1, &id)) {
  167.         printf("le: No ID PROM\n");
  168.         return 1;
  169.     }
  170.  
  171.     return lancereset(es, sip);
  172. }
  173.  
  174. /*
  175.  * Basic Lance initialization
  176.  * Returns 1 for error (after printing message), 0 for ok.
  177.  */
  178. int
  179. lancereset(es, sip)
  180.     register struct lance_softc *es;
  181.     struct saioreq *sip;
  182. {
  183.     register struct le_device *le = es->es_lance;
  184.     register struct le_init_block *ib = &es->es_ib;
  185.     int timeout = TIMEBOMB;
  186.     int i;
  187.  
  188. #ifdef DEBUG1
  189.     printf("le: lancereset(%x, %x)\n", es, sip);
  190. #endif DEBUG1
  191.  
  192.     /* Reset the chip */
  193.     le->le_rap = LE_CSR0;
  194.     le->le_csr = LE_STOP;
  195.  
  196.     /* Perform the basic initialization */
  197.     
  198.     /* Construct the initialization block */
  199.     bzero((caddr_t)&es->es_ib, sizeof (struct le_init_block));
  200.  
  201.     /* Leave the mode word 0 for normal operating mode */
  202.  
  203.     myetheraddr(&es->es_enaddr);
  204.  
  205.     /* Oh, for a consistent byte ordering among processors */
  206.     ib->ib_padr[0] = es->es_enaddr.ether_addr_octet[1];
  207.     ib->ib_padr[1] = es->es_enaddr.ether_addr_octet[0];
  208.     ib->ib_padr[2] = es->es_enaddr.ether_addr_octet[3];
  209.     ib->ib_padr[3] = es->es_enaddr.ether_addr_octet[2];
  210.     ib->ib_padr[4] = es->es_enaddr.ether_addr_octet[5];
  211.     ib->ib_padr[5] = es->es_enaddr.ether_addr_octet[4];
  212.  
  213.     /* Leave address filter 0 -- we don't want Multicast packets */
  214.  
  215.     ib->ib_rdrp.drp_laddr = (long)&es->es_rmd[0];
  216.     ib->ib_rdrp.drp_haddr = (long)&es->es_rmd[0] >> 16;
  217.     ib->ib_rdrp.drp_len  = 1;   /* 2 to the 1 power = 2 */
  218.     
  219.     ib->ib_tdrp.drp_laddr = (long)&es->es_tmd;
  220.     ib->ib_tdrp.drp_haddr = (long)&es->es_tmd >> 16;
  221.     ib->ib_tdrp.drp_len  = 0;   /* 2 to the 0 power = 1 */
  222.  
  223.     /* Clear all the descriptors */
  224.     bzero((caddr_t)es->es_rmd, 2 * sizeof (struct le_md));
  225.     bzero((caddr_t)&es->es_tmd, sizeof (struct le_md));
  226.  
  227.     /* Give the init block to the chip */
  228.     le->le_rap = LE_CSR1;    /* select the low address register */
  229.     le->le_rdp = (long)ib & 0xffff;
  230.  
  231.     le->le_rap = LE_CSR2;    /* select the high address register */
  232.     le->le_rdp = ((long)ib >> 16) & 0xff;
  233.  
  234.     le->le_rap = LE_CSR3;    /* Bus Master control register */
  235.     le->le_rdp = LE_BSWP;
  236.  
  237.     le->le_rap = LE_CSR0;    /* main control/status register */
  238.     le->le_csr = LE_INIT;
  239.  
  240.     while( ! (le->le_csr & LE_IDON) ) {
  241.         if (timeout-- <= 0) {
  242.             printf("le: cannot initialize\n");
  243.             return (1);
  244.         }
  245.     }
  246.     le->le_csr = LE_IDON;    /* Clear the indication */
  247.  
  248.     /* Hang out the receive buffers */
  249.     es->es_next_rmd = 0;
  250.  
  251.     install_buf_in_rmd(es->es_rbuf[0], &es->es_rmd[0]);
  252.     install_buf_in_rmd(es->es_rbuf[1], &es->es_rmd[1]);
  253.  
  254.     le->le_csr = LE_STRT;
  255.  
  256. #ifdef DEBUG1
  257.     printf("le: lancereset returns OK\n");
  258. #endif DEBUG1
  259.     return 0;        /* It all worked! */
  260. }
  261.  
  262. install_buf_in_rmd(buffer, rmd)
  263.     u_char *buffer;
  264.     register struct le_md *rmd;
  265. {
  266.     rmd->lmd_ladr = (u_short)buffer;
  267.     rmd->lmd_hadr = (long)buffer >> 16;
  268.     rmd->lmd_bcnt = -LANCERBUFSIZ;
  269.     rmd->lmd_mcnt = 0;
  270.     rmd->lmd_flags = LMD_OWN;
  271. }
  272.  
  273. /*
  274.  * Transmit a packet.
  275.  * If possible, just points to the packet without copying it anywhere.
  276.  */
  277. lancexmit(es, buf, count)
  278.     register struct lance_softc *es;
  279.     char *buf;
  280.     int count;
  281. {
  282.     register struct le_device *le = es->es_lance;
  283.     struct le_md *tmd = &es->es_tmd; /* Transmit Msg. Descriptor */
  284.     caddr_t tbuf;
  285.     int timeout = TIMEBOMB;
  286.  
  287. #ifdef DEBUG2
  288.     printf( "xmit np_blkno %x\n",
  289.         ((struct ndpack *)(buf+14))->np_blkno);
  290. #endif DEBUG2
  291.     /*
  292.      * We assume the buffer is in an area accessible by the chip.
  293.      * The caller of xmit is currently ndxmit(), which only sends
  294.      * an nd structure, which we happen to know is allocated in the
  295.      * right area (in fact, it's part of the struct nd which
  296.      * is the first thing in our own es structure).  If we wish to
  297.      * use xmit for some other purpose, the buffer might not be
  298.      * accessible by the chip, so to be general we ought to copy
  299.      * into some accessible place.  HOWEVER, PROM space is really tight,
  300.      * so this generality is not free.
  301.      */
  302. #ifdef PROM
  303.     tbuf = buf;
  304.     if (((int)tbuf & 0x00F00000) == 0)
  305.         (int)tbuf |= 0x00F00000;
  306. #else  PROM
  307. /* FIXME, constant address masks here! */
  308.     if ( ((int)buf & 0x0F000000) == 0x0F000000) { /* we can point to it */
  309.         tbuf = buf;
  310.     } else {
  311.         tbuf = (caddr_t)es->es_tbuf;
  312.         bcopy((caddr_t)buf, tbuf, count);
  313.     }
  314. #endif PROM
  315.     
  316.     tmd->lmd_hadr = (int)tbuf >> 16;
  317.     tmd->lmd_ladr = (u_short) tbuf;
  318.     tmd->lmd_bcnt = -count;
  319.     
  320. #ifdef notdef
  321.     if (tmd->lmd_bcnt < -MINPACKET)
  322.         tmd->lmd_bcnt = -MINPACKET;
  323. #endif notdef
  324.     tmd->lmd_flags3 = 0;
  325.     tmd->lmd_flags = LMD_STP | LMD_ENP | LMD_OWN;
  326.     
  327.     le->le_csr = LE_TDMD;
  328.  
  329.     do {
  330.         if ( le->le_csr & LE_TINT ) {
  331.         le->le_csr = LE_TINT; /* Clear interrupt */
  332.         break;
  333.         }
  334.     } while ( --timeout > 0);
  335.  
  336. /*****************************************************************************
  337.  * 10-Dec-85
  338.  *     ADD signal user that we have lost carrier (or couldn't find it).
  339.  *        This usually means that the cable is bad
  340.  *
  341.  *****************************************************************************/
  342.  
  343.     if (tmd->lmd_flags & LMD_ERR)
  344.         {
  345.         if (tmd->lmd_flags3 & TMD_LCAR)  /* (AMD Lance Transmit msg */
  346.                          /*  descriptor - 3 (TMD3)  */
  347.         printf("le: No Carrier\n");
  348.             }
  349. /*****************************************************************************/
  350.  
  351.     if ( (tmd->lmd_flags & LMD_ERR)
  352.     ||   (tmd->lmd_flags3 & TMD_BUFF)
  353.     ||   (timeout <= 0) ) {
  354. #ifdef DEBUG
  355.         printf("le: xmit failed - tmd1 flags %x tmd3 %x csr0 %x\n",
  356.                    tmd->lmd_flags, tmd->lmd_flags3, le->le_csr);
  357. #endif DEBUG
  358.         return (1);
  359.     }
  360.  
  361.     return (0);
  362. }
  363.  
  364. int
  365. lancepoll(es, buf)
  366.     register struct lance_softc *es;
  367.     char *buf;
  368. {
  369.     register struct le_device *le = es->es_lance;
  370.     register struct le_md *rmd;
  371.     register struct ether_header *header;
  372.     int length;
  373.  
  374. #ifdef DEBUG1
  375.     printf("le: poll\n");
  376. #endif DEBUG1
  377.     if ( ! (le->le_csr & LE_RINT)  )
  378.         return (0);        /* No packet yet */
  379.  
  380. #ifdef DEBUG1
  381.     printf("le: received packet\n");
  382. #endif DEBUG1
  383.  
  384.     le->le_csr = LE_RINT;         /* Clear interrupt */
  385.  
  386.     rmd = &es->es_rmd[es->es_next_rmd];
  387.  
  388.     if ( (rmd->lmd_flags & ~RMD_OFLO) != (LMD_STP|LMD_ENP) ) {
  389. #ifdef DEBUG
  390.         printf("Receive packet error - rmd flags %x\n",rmd->lmd_flags);
  391. #endif DEBUG
  392.         length = 0;
  393.         goto restorebuf;
  394.     }
  395.  
  396.     /* Get input data length and a pointer to the ethernet header */
  397.  
  398.     length = rmd->lmd_mcnt - 4;    /* don't count the 4 CRC bytes */
  399.     header = (struct ether_header *)es->es_rbuf[es->es_next_rmd];
  400.  
  401. #ifdef LANCEBUG
  402.     /*
  403.      * Check for unreported packet errors.  Rev C of the LANCE chip
  404.      * has a bug which can cause "random" bytes to be prepended to
  405.      * the start of the packet.  The work-around is to make sure that
  406.      * the Ethernet destination address in the packet matches our
  407.      * address.
  408.      */
  409. #define ether_addr_not_equal(a,b)    \
  410.     (  ( *(long  *)(&a.ether_addr_octet[0]) != \
  411.          *(long  *)(&b.ether_addr_octet[0]) )  \
  412.     || ( *(short *)(&a.ether_addr_octet[4]) != \
  413.          *(short *)(&b.ether_addr_octet[4]) )  \
  414.     )
  415.  
  416.         if( ether_addr_not_equal(header->ether_dhost, es->es_enaddr)
  417.     &&  ether_addr_not_equal(header->ether_dhost, etherbroadcastaddr) ) {
  418.         printf("le: LANCE Rev C Extra Byte(s) bug; Packet punted\n");
  419.         length = 0;
  420.         /* Don't return directly; restore the buffer first */
  421.     }
  422. #endif LANCEBUG
  423.  
  424. #ifdef DEBUG2
  425.         if( header->ether_dhost.ether_addr_octet[0] == 0xff )
  426.         printf("Broadcast packet\n");
  427.     else    printf("recv np_blkno %x\n",
  428.                 ((struct ndpack *)(buf+14))->np_blkno);
  429. #endif DEBUG2
  430.     
  431.     /* Copy packet to user's buffer */
  432.     if ( length > 0 )
  433.         bcopy((caddr_t)header, buf, length);
  434.  
  435. restorebuf:
  436.     rmd->lmd_mcnt = 0;
  437.     rmd->lmd_flags = LMD_OWN;
  438.  
  439.     /* Get ready to use the other buffer next time */
  440.     /* What about errors ? */
  441.     es->es_next_rmd = 1 - es->es_next_rmd;
  442.  
  443.     return (length);
  444. }
  445.  
  446. /*
  447.  * Close down Lance Ethernet device.
  448.  * On the Model 25, we reset the chip and take it off the wire, since
  449.  * it is sharing main memory with us (occasionally reading and writing),
  450.  * and most programs don't know how to deal with that -- they just assume
  451.  * that main memory is theirs to play with.
  452.  */
  453. lanceclose(sip)
  454.     struct saioreq *sip;
  455. {
  456.     struct lance_softc *es = (struct lance_softc *) sip->si_devdata;
  457.     struct le_device *le = es->es_lance;
  458.  
  459.     /* Reset the chip */
  460.     le->le_rap = LE_CSR0;
  461.     le->le_csr = LE_STOP;
  462. }
  463. #endif    M25
  464.